package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.annotation.Arithmetic;
import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.var.VarDrivingEcoNo;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;
import com.navinfo.platform.trip.common.util.BigDecimalUtils;

import java.math.BigDecimal;

/**
 * 东风新版，非ECO经济转速驾驶算法<br/>
 *      1.解析发动机转速报文数值，一秒一个数值；<br/>
 *      2.将数值为负数、大于3000的值去掉，按临近前后5个数值替代；<br/>
 *      3.将瞬时发动机转速值分布到以50转为一个间隔的转速区内，同时累计计数；<br/>
 *      4.当 V>30KM/h 时，每3分钟统计计算该行程发动机转速值分布在1000-1700<br/>
 *      5.转范围内的比例，阈值设计为<50%;<br/>
 *      6.当比例数值小于阈值时，计数 1 次；<br/>
 *      7.行程结束，累计计算非经济转速行驶事件次数，累计非经济转速行驶时间总占比，累计计算非经济转速行驶总油耗、总里程。<br/>
 *
 *      非经济转速行驶总占比：速度大于>30并且转速不在1000-1700的时间/速度>30的行程时间
 *      非经济转速行驶总油耗：速度大于>30并且转速不在1000-1700的油耗
 *      非经济转速行驶里程：速度大于>30并且转速不在1000-1700的里程
 *
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
@Arithmetic(name = "东风新版，非ECO经济转速驾驶算法")
public class DrivingEcoNo_DFN extends AbstractArithmetic<VarDrivingEcoNo> {
    private static final EventType EVENT_TYPE = EventType.noEcoDriving;
    /**
     * 非ECO驾驶，速度阀值：单位km/h 默认30
     */
    private int speedThreshold = ConfigMap.getInteger("DFN_NoECO_Speed_Threshold");
    /**
     * 非ECO驾驶，比例阀值：单位% 默认50
     */
    private int ratioThreshold = ConfigMap.getInteger("DFN_NoECO_Ratio_Threshold");
    /**
     * 非ECO驾驶，统计时长阀值：单位ms 默认1000 * 180
     */
    private long timeThreshold = 1000 * ConfigMap.getInteger("DFN_NoECO_Duration_Threshold");

    @Override
    public void calculate() {
        logger.debug("进入东风新版，非ECO经济驾驶算法.[terminalId:{}]", terminalId);
        VarDrivingEcoNo var = getObj();
        CommonData commonData = getCommonData();
        int rotation = commonData.getRotation();

        //转速与速度在合理范围内
        if(rotation>0 && rotation<3000 && commonData.getSpeedKmh()>speedThreshold){
            int dffTime = commonData.getDffTime();
            var.addStatisticDuration(dffTime);

            //经济转速区间
            if(rotation>1000 && rotation<1700){
                var.addStatisticEcoNumber(1);
                var.addEcoDuration(dffTime);
            }
            //非经济转速区间
            else{
                var.addStatisticNoEcoNumber(1);
                var.addNoEcoDuration(dffTime);
                var.addNoEcoFuel(commonData.getDffFuel());
                var.addNoEcoMileage(commonData.getDffMileage());
            }
        }else{
            //重置统计时长
            var.setStatisticDuration(0);
        }

        //每timeThreshold统计一次非经济转速行驶事件
        if(var.getStatisticDuration() > timeThreshold){
            BigDecimal ratio = BigDecimalUtils.divide(var.getStatisticEcoNumber(), var.getStatisticEcoNumber()+var.getStatisticNoEcoNumber(), 2);
            if(BigDecimal.valueOf(100).multiply(ratio).intValue() < ratioThreshold){
                var.addNoEcoNumber(1);
            }

            //重置统计时长
            var.setStatisticDuration(0);
        }


        logger.debug("东风新版，非ECO经济驾驶算法结束.[terminalId:{}]", terminalId);
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarDrivingEcoNo var = getObj();
        statisticDataOut.setNoEcoNumber_DFN(var.getNoEcoNumber());
        statisticDataOut.setNoEcoMileage_DFN(ArithmeticUtils.mileageMToM(var.getNoEcoMileage()));
        statisticDataOut.setNoEcoFuel_DFN(ArithmeticUtils.fuelMlToMl(var.getNoEcoFuel()));
        statisticDataOut.setNoEcoDuration_DFN(ArithmeticUtils.timeMsToSecond(var.getNoEcoDuration()));
        long durationSum = var.getNoEcoDuration() + var.getEcoDuration();
        BigDecimal ratio = durationSum==0 ? BigDecimal.valueOf(0) : BigDecimalUtils.divide(var.getNoEcoDuration(), durationSum, 2);
        statisticDataOut.setNoEcoProportion_DFN(new BigDecimal("100").multiply(ratio).intValue());
    }
}
